import {
  log2_d,
  getCode,
  getLonLat,
  getCodeFromRCH,
  rowcoltierNumber,
}
  from '@/dqg/EncodingConversion';
// import { surfaceInstance, outlineInstanceArray } from '../dqg/PrimitivesInstance';
import { minLongitudeDiff, degenerateSouthEdge, degenerateRow } from './constant';

/**
 * 将DQG格网行列号转为均匀四叉树格网行列号
 * @param {Array} lineArr 包含航线顶点的经度，纬度
 * @param {Number} level 剖分层次
 * @param {Array} relativeXY 存储行列号的数组
 */
const dqgToUniformgrid = (lineArr, level, relativeXY) => {
  for (let i = 0; i < lineArr.length - 1; i += 2) {
    const dqgGridInfo = rowcoltierNumber(level, lineArr[i], lineArr[i + 1]);  // gridInfo: [j, i, height, Q]
    let code = getCode(level, lineArr[i], lineArr[i + 1], 0);
    let grid = getLonLat(code);
    // console.log(degenerateSouthEdge.includes(grid.south));
    if (degenerateRow.includes(dqgGridInfo[1]) || degenerateSouthEdge.includes(grid.south)) {
      // console.log(grid);
      const pointLon = lineArr[i] - dqgGridInfo[3] * 90;

      let uniformGridCol = Math.floor(pointLon / minLongitudeDiff[level]);

      if (uniformGridCol === Math.pow(2, level)) {
        uniformGridCol -= 1;
      }

      dqgGridInfo[0] = uniformGridCol;


      relativeXY.push(dqgGridInfo);

    } else {
      relativeXY.push(dqgGridInfo);
    }
  }
}

/**
 * 用于将均匀四叉树格网行列号转换为DQG格网行列号
 * @param {Array} uniformGridXY 均匀四叉树格网行列号
 * @param {Number} level 剖分层次
 * @param {Map} modifiedTile 用于剔除重复的DQG格网
 * @param {Array} DQGArray 存储每个DQG格网对应的编码
 */
const uniformGridToDqg = (uniformGridXY, level, modifiedTile, DQGArray) => {
  const maxCols = Math.pow(2, level); // 在该剖分等级下，行对应的最多列数
  uniformGridXY.forEach(item => {
    const cols = 1 << log2_d(item.row + 1);  // 该行对应的列数

    if (cols !== maxCols) {
      let n = maxCols / cols; // n表示DQG格网中每一列对应均匀四叉树格网有多少列
      let dqgCol = Math.floor(item.col / n);

      item.col = dqgCol; // 将该格网中的均匀四叉树列号改为DQG列号
      let flag = item.col + '' + item.row;
      if (!modifiedTile.has(flag)) {
        modifiedTile.add(flag);
        let code = getCodeFromRCH(item.col, item.row, item.h, item.Q, level);
        DQGArray.push(code);
      }

    } else {
      let code = getCodeFromRCH(item.col, item.row, item.h, item.Q, level);
      DQGArray.push(code);
    }
  })
}

/**
 * 
 * @param {Array} prevPoint 第一个点的数据 [col, row]
 * @param {Array} nextPoint 第二个点的数据 [col, row]
 * @param {Array} uniformGridXY 用来存储计算出来的均匀四叉树格网坐标
 */
const lineBresenham = (relativeXY, uniformGridXY, DQGArray, level) => {
  for (let i = 1; i < relativeXY.length; i++) {
    let prevPoint = relativeXY[i - 1];
    let nextPoint = relativeXY[i];
    let dx = Math.abs(nextPoint[0] - prevPoint[0]);
    let dy = Math.abs(nextPoint[1] - prevPoint[1]);
    let x = prevPoint[0];
    let y = prevPoint[1];
    let sx = nextPoint[0] > prevPoint[0] ? 1 : -1;
    let sy = nextPoint[1] > prevPoint[1] ? 1 : -1;

    if (dx > dy) {
      let e = -dx;
      for (let i = 0; i < dx; i++) {
        x += sx;
        e += 2 * dy;
        if (e >= 0) {
          y += sy;
          e -= 2 * dx;
        }
        let code = getCodeFromRCH(x, y, 0, 1, level);
        DQGArray.push(code);
        uniformGridXY.push({
        col: x,
        row: y,
        h: 0,
        Q: 1,
        level: level
      });
      }
    } else {
      let e = -dy;
      for (let i = 0; i < dy; i++) {
        y += sy;
        e += 2 * dx;
        if (e >= 0) {
          x += sx;
          e -= 2 * dy;
        }
        let code = getCodeFromRCH(x, y, 0, 1, level);
        DQGArray.push(code);
      }
      uniformGridXY.push({
        col: x,
        row: y,
        h: 0,
        Q: 1,
        level: level
      });
    }
  }
}

/**
 * 
 * @param {Array} lineArr 包含航线顶点的经度，纬度
 * @param {Number} level 剖分层次
 */
const fill2dLineAlgorithm = (lineArr, level) => {

  const relativeXY = []; // 存储航线顶点坐标的行列号信息的数组
  const modifiedTile = new Set();
  const uniformGridXY = [];
  const DQGArray = [];
  // for (let i = 0; i < lineArr.length - 1; i += 2) {
  //   let dqgGridInfo = rowcoltierNumber(level, lineArr[i], lineArr[i + 1]); // dqgGridInfo包含信息：[col, row, h, Q]
  //   relativeXY.push(dqgGridInfo);
  // }
  dqgToUniformgrid(lineArr, level, relativeXY);
  lineBresenham(relativeXY, uniformGridXY, DQGArray, level);
  // uniformGridToDqg(uniformGridXY, level, modifiedTile, DQGArray)
  console.log(DQGArray);
  return DQGArray;
}



/**
 * 
 * @param {*} viewer 
 * @param {*} level 
 * @param {*} url 
 * @param {*} cameraInfo 
 */
export function drawOneAirLine(viewer, level, url, cameraInfo) {
  const xhr = new XMLHttpRequest();
  xhr.open("get", url);
  xhr.send(null);
  xhr.onload = function () {
    if (xhr.status === 200) {
      const json = JSON.parse(xhr.responseText);
      const lineArr = [];
      let tempLon = 0, tempLat;
      for (let i = 0; i < json.length; i++) {
        tempLon = Number(json[i].longitude);
        tempLon = tempLon > 0 ? tempLon : tempLon + 360.0;
        tempLat = Number(json[i].latitude);
        if (tempLat < 0) {
          tempLon = 360.0 - tempLon;
        }
        // 经度、纬度、高度
        lineArr.push(Number(tempLon));
        lineArr.push(tempLat);
        // lineArr.push(Number(json[i].height) * 10);
      }
      // console.log(lineArr);
      // 绘制矢量航线
      viewer.entities.add({
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArray(lineArr),
          outline: true,
          outlineColor: Cesium.Color.ORANGERED,
          outlineWidth: 1,
          material: Cesium.Color.fromRandom({ alpha: 1.0 })
        }
      });

      const DQGArray = fill2dLineAlgorithm(lineArr, level);

      // console.log(DQGArray);

      const DQGTiles = [];
      for (const code of DQGArray) {
        let tileInfo = getLonLat(code);
        DQGTiles.push(
          tileInfo
        )
      }

      // console.table(DQGTiles);
      const surfaceInstances = [];

      for (let i = 0; i < DQGTiles.length; i++) {
        surfaceInstances.push(
          new Cesium.GeometryInstance({
            geometry: new Cesium.RectangleOutlineGeometry({
              rectangle: Cesium.Rectangle.fromDegrees(DQGTiles[i].west, DQGTiles[i].south, DQGTiles[i].east, DQGTiles[i].north),
            }),
            id: 'rectangle',
            attributes: {
              color: new Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
            }
          })
        )
      }

      viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: surfaceInstances,
        asynchronous: false,
        compressVertices: false,
        cull: false,
        appearance: new Cesium.PerInstanceColorAppearance({
          flat: true,
          translucent: false,
          renderState: {
            lineWidth: 1
          }
        })
      }));
    }
  }
}
